home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2007 September / PCWSEP07.iso / Software / Resources / Developers / XAMPP 1.5.4 / Windows installer / xampp-win32-1.5.4-installer.exe / xampp / php / pear / Crypt / Blowfish.php next >
Encoding:
PHP Script  |  2005-12-02  |  8.2 KB  |  318 lines

  1. <?php
  2. /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
  3.  
  4. /**
  5.  * Crypt_Blowfish allows for encryption and decryption on the fly using
  6.  * the Blowfish algorithm. Crypt_Blowfish does not require the mcrypt
  7.  * PHP extension, it uses only PHP.
  8.  * Crypt_Blowfish support encryption/decryption with or without a secret key.
  9.  *
  10.  *
  11.  * PHP versions 4 and 5
  12.  *
  13.  * LICENSE: This source file is subject to version 3.0 of the PHP license
  14.  * that is available through the world-wide-web at the following URI:
  15.  * http://www.php.net/license/3_0.txt.  If you did not receive a copy of
  16.  * the PHP License and are unable to obtain it through the web, please
  17.  * send a note to license@php.net so we can mail you a copy immediately.
  18.  *
  19.  * @category   Encryption
  20.  * @package    Crypt_Blowfish
  21.  * @author     Matthew Fonda <mfonda@php.net>
  22.  * @copyright  2005 Matthew Fonda
  23.  * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
  24.  * @version    CVS: $Id: Blowfish.php,v 1.81 2005/05/30 18:40:36 mfonda Exp $
  25.  * @link       http://pear.php.net/package/Crypt_Blowfish
  26.  */
  27.  
  28.  
  29. require_once 'PEAR.php';
  30.  
  31.  
  32. /**
  33.  *
  34.  * Example usage:
  35.  * $bf = new Crypt_Blowfish('some secret key!');
  36.  * $encrypted = $bf->encrypt('this is some example plain text');
  37.  * $plaintext = $bf->decrypt($encrypted);
  38.  * echo "plain text: $plaintext";
  39.  *
  40.  *
  41.  * @category   Encryption
  42.  * @package    Crypt_Blowfish
  43.  * @author     Matthew Fonda <mfonda@php.net>
  44.  * @copyright  2005 Matthew Fonda
  45.  * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
  46.  * @link       http://pear.php.net/package/Crypt_Blowfish
  47.  * @version    1.0.1
  48.  * @access     public
  49.  */
  50. class Crypt_Blowfish
  51. {
  52.     /**
  53.      * P-Array contains 18 32-bit subkeys
  54.      *
  55.      * @var array
  56.      * @access private
  57.      */
  58.     var $_P = array();
  59.     
  60.     
  61.     /**
  62.      * Array of four S-Blocks each containing 256 32-bit entries
  63.      *
  64.      * @var array
  65.      * @access private
  66.      */
  67.     var $_S = array();
  68.  
  69.     /**
  70.      * Mcrypt td resource
  71.      *
  72.      * @var resource
  73.      * @access private
  74.      */
  75.     var $_td = null;
  76.  
  77.     /**
  78.      * Initialization vector
  79.      *
  80.      * @var string
  81.      * @access private
  82.      */
  83.     var $_iv = null;
  84.  
  85.     
  86.     /**
  87.      * Crypt_Blowfish Constructor
  88.      * Initializes the Crypt_Blowfish object, and gives a sets
  89.      * the secret key
  90.      *
  91.      * @param string $key
  92.      * @access public
  93.      */
  94.     function Crypt_Blowfish($key)
  95.     {
  96.         if (extension_loaded('mcrypt')) {
  97.             $this->_td = mcrypt_module_open(MCRYPT_BLOWFISH, '', 'ecb', '');
  98.             $this->_iv = mcrypt_create_iv(8, MCRYPT_RAND);
  99.         }
  100.         $this->setKey($key);
  101.     }
  102.     
  103.     /**
  104.      * Deprecated isReady method
  105.      *
  106.      * @return bool
  107.      * @access public
  108.      * @deprecated
  109.      */
  110.     function isReady()
  111.     {
  112.         return true;
  113.     }
  114.     
  115.     /**
  116.      * Deprecated init method - init is now a private
  117.      * method and has been replaced with _init
  118.      *
  119.      * @return bool
  120.      * @access public
  121.      * @deprecated
  122.      * @see Crypt_Blowfish::_init()
  123.      */
  124.     function init()
  125.     {
  126.         $this->_init();
  127.     }
  128.     
  129.     /**
  130.      * Initializes the Crypt_Blowfish object
  131.      *
  132.      * @access private
  133.      */
  134.     function _init()
  135.     {
  136.         $defaults = new Crypt_Blowfish_DefaultKey();
  137.         $this->_P = $defaults->P;
  138.         $this->_S = $defaults->S;
  139.     }
  140.             
  141.     /**
  142.      * Enciphers a single 64 bit block
  143.      *
  144.      * @param int &$Xl
  145.      * @param int &$Xr
  146.      * @access private
  147.      */
  148.     function _encipher(&$Xl, &$Xr)
  149.     {
  150.         for ($i = 0; $i < 16; $i++) {
  151.             $temp = $Xl ^ $this->_P[$i];
  152.             $Xl = ((($this->_S[0][($temp>>24) & 255] +
  153.                             $this->_S[1][($temp>>16) & 255]) ^
  154.                             $this->_S[2][($temp>>8) & 255]) +
  155.                             $this->_S[3][$temp & 255]) ^ $Xr;
  156.             $Xr = $temp;
  157.         }
  158.         $Xr = $Xl ^ $this->_P[16];
  159.         $Xl = $temp ^ $this->_P[17];
  160.     }
  161.     
  162.     
  163.     /**
  164.      * Deciphers a single 64 bit block
  165.      *
  166.      * @param int &$Xl
  167.      * @param int &$Xr
  168.      * @access private
  169.      */
  170.     function _decipher(&$Xl, &$Xr)
  171.     {
  172.         for ($i = 17; $i > 1; $i--) {
  173.             $temp = $Xl ^ $this->_P[$i];
  174.             $Xl = ((($this->_S[0][($temp>>24) & 255] +
  175.                             $this->_S[1][($temp>>16) & 255]) ^
  176.                             $this->_S[2][($temp>>8) & 255]) +
  177.                             $this->_S[3][$temp & 255]) ^ $Xr;
  178.             $Xr = $temp;
  179.         }
  180.         $Xr = $Xl ^ $this->_P[1];
  181.         $Xl = $temp ^ $this->_P[0];
  182.     }
  183.     
  184.     
  185.     /**
  186.      * Encrypts a string
  187.      *
  188.      * @param string $plainText
  189.      * @return string Returns cipher text on success, PEAR_Error on failure
  190.      * @access public
  191.      */
  192.     function encrypt($plainText)
  193.     {
  194.         if (!is_string($plainText)) {
  195.             PEAR::raiseError('Plain text must be a string', 0, PEAR_ERROR_DIE);
  196.         }
  197.  
  198.         if (extension_loaded('mcrypt')) {
  199.             return mcrypt_generic($this->_td, $plainText);
  200.         }
  201.  
  202.         $cipherText = '';
  203.         $len = strlen($plainText);
  204.         $plainText .= str_repeat(chr(0),(8 - ($len%8))%8);
  205.         for ($i = 0; $i < $len; $i += 8) {
  206.             list(,$Xl,$Xr) = unpack("N2",substr($plainText,$i,8));
  207.             $this->_encipher($Xl, $Xr);
  208.             $cipherText .= pack("N2", $Xl, $Xr);
  209.         }
  210.         return $cipherText;
  211.     }
  212.     
  213.     
  214.     /**
  215.      * Decrypts an encrypted string
  216.      *
  217.      * @param string $cipherText
  218.      * @return string Returns plain text on success, PEAR_Error on failure
  219.      * @access public
  220.      */
  221.     function decrypt($cipherText)
  222.     {
  223.         if (!is_string($cipherText)) {
  224.             PEAR::raiseError('Chiper text must be a string', 1, PEAR_ERROR_DIE);
  225.         }
  226.  
  227.         if (extension_loaded('mcrypt')) {
  228.             return mdecrypt_generic($this->_td, $cipherText);
  229.         }
  230.  
  231.         $plainText = '';
  232.         $len = strlen($cipherText);
  233.         $cipherText .= str_repeat(chr(0),(8 - ($len%8))%8);
  234.         for ($i = 0; $i < $len; $i += 8) {
  235.             list(,$Xl,$Xr) = unpack("N2",substr($cipherText,$i,8));
  236.             $this->_decipher($Xl, $Xr);
  237.             $plainText .= pack("N2", $Xl, $Xr);
  238.         }
  239.         return $plainText;
  240.     }
  241.     
  242.     
  243.     /**
  244.      * Sets the secret key
  245.      * The key must be non-zero, and less than or equal to
  246.      * 56 characters in length.
  247.      *
  248.      * @param string $key
  249.      * @return bool  Returns true on success, PEAR_Error on failure
  250.      * @access public
  251.      */
  252.     function setKey($key)
  253.     {
  254.         if (!is_string($key)) {
  255.             PEAR::raiseError('Key must be a string', 2, PEAR_ERROR_DIE);
  256.         }
  257.  
  258.         $len = strlen($key);
  259.  
  260.         if ($len > 56 || $len == 0) {
  261.             PEAR::raiseError('Key must be less than 56 characters and non-zero. Supplied key length: ' . $len, 3, PEAR_ERROR_DIE);
  262.         }
  263.  
  264.         if (extension_loaded('mcrypt')) {
  265.             mcrypt_generic_init($this->_td, $key, $this->_iv);
  266.             return true;
  267.         }
  268.  
  269.         require_once 'Blowfish/DefaultKey.php';
  270.         $this->_init();
  271.         
  272.         $k = 0;
  273.         $data = 0;
  274.         $datal = 0;
  275.         $datar = 0;
  276.         
  277.         for ($i = 0; $i < 18; $i++) {
  278.             $data = 0;
  279.             for ($j = 4; $j > 0; $j--) {
  280.                     $data = $data << 8 | ord($key{$k});
  281.                     $k = ($k+1) % $len;
  282.             }
  283.             $this->_P[$i] ^= $data;
  284.         }
  285.         
  286.         for ($i = 0; $i <= 16; $i += 2) {
  287.             $this->_encipher($datal, $datar);
  288.             $this->_P[$i] = $datal;
  289.             $this->_P[$i+1] = $datar;
  290.         }
  291.         for ($i = 0; $i < 256; $i += 2) {
  292.             $this->_encipher($datal, $datar);
  293.             $this->_S[0][$i] = $datal;
  294.             $this->_S[0][$i+1] = $datar;
  295.         }
  296.         for ($i = 0; $i < 256; $i += 2) {
  297.             $this->_encipher($datal, $datar);
  298.             $this->_S[1][$i] = $datal;
  299.             $this->_S[1][$i+1] = $datar;
  300.         }
  301.         for ($i = 0; $i < 256; $i += 2) {
  302.             $this->_encipher($datal, $datar);
  303.             $this->_S[2][$i] = $datal;
  304.             $this->_S[2][$i+1] = $datar;
  305.         }
  306.         for ($i = 0; $i < 256; $i += 2) {
  307.             $this->_encipher($datal, $datar);
  308.             $this->_S[3][$i] = $datal;
  309.             $this->_S[3][$i+1] = $datar;
  310.         }
  311.         
  312.         return true;
  313.     }
  314.     
  315. }
  316.  
  317. ?>
  318.